#pragma once
template <typename E, int M>
struct SqQueue
{
    E elem[M];
    int front, rear;
};

template <typename E, int M>
void InitQueue(SqQueue<E,M> &Q)
{
    Q.front = Q.rear = 0;
}

template <typename E, int M>
bool QueueEmpty(const SqQueue<E,M> &Q)
{
    return Q.front == Q.rear;
}

template <typename E, int M>
void EnQueue(SqQueue<E,M> &Q, E e)
{
    if ((Q.rear + 1) % M == Q.front) throw "Queue full";
    Q.elem[Q.rear] = e;
    Q.rear = (Q.rear + 1) % M;
}

template <typename E, int M>
void DeQueue(SqQueue<E,M> &Q, E &e)
{
    if (Q.front == Q.rear) throw "Queue empty";
    e = Q.elem[Q.front];
    Q.front = (Q.front + 1) % M;
}

template <typename E, int M>
void DeQueue(SqQueue<E,M> &Q)
{
    if (Q.front == Q.rear) throw "Queue empty";
    Q.front = (Q.front + 1) % M;
}

template <typename E, int M>
void GetHead(const SqQueue<E,M> &Q, E &e)
{
    if (Q.front == Q.rear) throw "Queue empty";
    e = Q.elem[Q.front];
}

template <typename E, int M>
E GetHead(const SqQueue<E,M> &Q)
{
    if (Q.front == Q.rear) throw "Queue empty";
    return Q.elem[Q.front];
}
